/*
 * Controller.h
 *
 *  Created on: 30/10/2011
 *      Author: godinho
 */

#ifndef CONTROLLER_H_
#define CONTROLLER_H_

class SimulationNode;
class SimulatorOutput;
class Network;
class TLSPhase;
class NodeInput;

/**
 * This class controls all mesoscopic simulations. Here are implemented
 * simulations main loop.
 */
class Controller {
public:
	/**
	 * Build simulation controller
	 *
	 * @paran net Network used on simulation
	 */
	Controller(Network* net);

	/**
	 * Destroi controller
	 */
	virtual ~Controller();

	/**
	 * Start simulation
	 */
	void startSimulation(int numTimesteps);

	/**
	 * Stop simulation.
	 *
	 * The current step of simulation is completed executed before the simulation
	 * stops.
	 */
	void stopSimulation();

	/**
	 * Associate an object that will receive simulation output.
	 */
	void setOutput(SimulatorOutput* output);

protected:
	/**
	 * Main loop.
	 */
	void mainLoop();

	/**
	 * Move all cars on simulation.
	 */
	void simulateNodes();

	/**
	 * Move cars on a node
	 */
	void moveCarsNode(SimulationNode* node);

	/**
	 * Update tls signal
	 */
	void updateTLS(SimulationNode* node);

	/**
	 * Decrement time to arrive to destine of each car bundle present on
	 * NodeInputs from a Node. All cars are removed from onTrip state and put
	 * to toBeTransfered state(all this controlled by NodeInput object). And then
	 * comes the Controller role to all this crap: take the cars on toBeTranfered
	 * state and give them a nice end.
	 *
	 * Remenbering structure:
	 * 	<p>
	 * 		Each node has a set of NodeInputs objects. These objects are
	 * 		associated to each incoming node (Ex.: Given nodes X and Y,
	 * 		a car can reach Y from X, then we call X as incoming node and Y as
	 * 		target node; think on an Edge as the context to all this talk of
	 * 		terms that there are only relational means). Those node inputs object
	 * 		are the guys who manage all data related to cars on our structure,
	 * 		so If you're looking for a car just take a node and check all its
	 * 		NodeInput objects.
	 *
	 * 	Tip: Sometimes I think that all my explanations just generate more things
	 * 		 to be explained. I'm on a fucking explanation loop.
	 *
	 * 	Tip2: If the means of this object changes someday I'll be very screwed.
	 * 		  Just think about updates on all this duplicated definitions?
	 * 		  Be something more clever and start to do your documentation on
	 * 		  the right classes.
	 * 	</p>
	 *
	 * 	@param ni Node input that will be updated
	 * 	@param node Node which ni has came from.
	 */
	void updateOnTripCars(NodeInput* ni, SimulationNode* node);

	/**
	 * Generate new cars
	 */
	void generateCars();

	/**
	 * Check all links allowed on a phase, and distribute the cars between
	 * the different targets.
	 */
	void moveCarsOnLinks(SimulationNode* node);

private:
	bool mSimulationEnded;
	int mStep;
	int mNumSteps;
	Network* mNetwork;
	SimulatorOutput* mSimulatorOutput;
};

#endif /* CONTROLLER_H_ */
